package com.efamily.ewallet.client;

import java.util.Date;

import com.efamily.ewallet.client.common.CustomEventType;
import com.efamily.ewallet.client.common.CustomEvents;
import com.efamily.ewallet.client.common.bean.UserBean;
import com.efamily.ewallet.client.services.IAuthorizationServiceAsync;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.mvc.Dispatcher;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonBar;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.FillLayout;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.rpc.AsyncCallback;

public abstract class LoginWidget extends Composite {
	ContentPanel mainPanel = new ContentPanel();
	private FormPanel loginPanel = new FormPanel();
	private IAuthorizationServiceAsync authorizationService = IAuthorizationServiceAsync.instance;
	private TextField<String> login = new TextField<String>();
	private TextField<String> password = new TextField<String>();
	private Button loginBtn = new Button("Log in");
	private ButtonBar bbar = new ButtonBar();

	public LoginWidget() {
		mainPanel.add(loginPanel);
		mainPanel.setLayout(new FillLayout());
		mainPanel.setHeaderVisible(false);
		mainPanel.setCollapsible(true);
		mainPanel.setFrame(false);
		mainPanel.setBodyBorder(false);
		initComponent(mainPanel);
		buildLoginPanel();
		Dispatcher.get().addListener(
				CustomEvents.LOGED_OUT.getEventType(),
				new Listener<BaseEvent>() {
					public void handleEvent(BaseEvent be) {
						loginPanel.expand();
					}
				});
	}

	private void buildLoginPanel() {
		loginPanel.setHeaderVisible(false);
		loginPanel.setFrame(false);
		loginPanel.setBodyBorder(false);
		loginPanel.setCollapsible(true);
		login.setFieldLabel("Login");
		login.addListener(Events.Attach, new Listener<BaseEvent>() {
			public void handleEvent(BaseEvent be) {
				login.setValue("");
			}
		});
		loginPanel.add(login, new FormData("90%"));
		password.setFieldLabel("Password");
		password.setPassword(true);
		password.addListener(Events.Attach, new Listener<BaseEvent>() {
			public void handleEvent(BaseEvent be) {
				password.setValue("");
			}
		});
		loginPanel.add(password, new FormData("90%"));
		loginBtn.setWidth(60);

		bbar.setAlignment(HorizontalAlignment.RIGHT);
		bbar.add(loginBtn);
		loginPanel.add(bbar, new FormData("90%"));
		loginBtn.addSelectionListener(new SelectionListener<ButtonEvent>() {
			@Override
			public void componentSelected(ButtonEvent be) {
				authorizationService.login(login.getValue(), password
						.getValue(), new AsyncCallback<UserBean>() {

					public void onFailure(Throwable caught) {
						loginFailure();
					}

					public void onSuccess(UserBean result) {
						if (result != null) {
							loginSuccess(result);
							loginPanel.collapse();
							Cookies.setCookie("StreamLineSSO", result
									.getTicketValue(), new Date());
						} else {
							loginFailure();
						}
					}
				});
			}
		});
	}

	public void insertButton(Component item, int index) {
		bbar.insert(item, index);
	}

	public void addButton(Component item) {
		bbar.add(item);
	}

	protected abstract void loginSuccess(UserBean result);

	protected void loginFailure() {
		password.setValue("");
		login.markInvalid("Credential is invalid. Please try again.");
		password.markInvalid("Credential is invalid. Please try again.");
	}
}
